/*
 * @Author: jiu yin
 * @Date: 2023-05-11 13:52:59
 * @LastEditTime: 2025-08-18 17:27:22
 * @LastEditors: jiu yin zhen jing
 * @FilePath: \one-half-vue3-2025-3-7\src\utils\index.js
 * jiu
 */
/**
 * @description:  深拷贝
 * @return {*}
 */

export function deepClone(obj) {
	const typeOfStr = Object.prototype.toString;
	const objType = typeOfStr.call(obj).slice(8, -1);
	// console.log(obj);
	if (objType !== "Object" && objType !== "Array") return obj;

	const newObj = objType === "Array" ? [] : {};

	if (objType == "Object") {
		for (let key in obj) {
			newObj[key] = deepClone(obj[key]);
		}
	}

	if (objType == "Array") {
		obj.forEach((item, index) => {
			newObj.push(deepClone(item));
		});
	}

	return newObj;
}

//promise微任务
export function asyncFn(fn) {
	return Promise.resolve().then(fn);
}
//mutation微任务
export function mutationFn(fn) {
	let ob = new MutationObserver(fn);
	let text = document.createTextNode("0");
	ob.observe(text, { characterData: true });
	text.data = 1;
}

/**
 * 格式化
 * @param { Date } day
 * @param { String } fmt
 * @returns { String } time
 */
export function parseTime(time, cFormat) {
	if (arguments.length === 0 || !time) {
		return null;
	}
	const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
	let date;
	if (typeof time === "object") {
		date = time;
	} else {
		if (typeof time === "string") {
			if (/^[0-9]+$/.test(time)) {
				// support "1548221490638"
				time = parseInt(time);
			} else {
				time = time.replace(new RegExp(/-/gm), "/");
			}
		}

		if (typeof time === "number" && time.toString().length === 10) {
			time = time * 1000;
		}
		date = new Date(time);
	}
	const formatObj = {
		y: date.getFullYear(),
		m: date.getMonth() + 1,
		d: date.getDate(),
		h: date.getHours(),
		i: date.getMinutes(),
		s: date.getSeconds(),
		a: date.getDay(),
	};
	const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
		const value = formatObj[key];
		// Note: getDay() returns 0 on Sunday
		if (key === "a") {
			return ["日", "一", "二", "三", "四", "五", "六"][value];
		}
		return value.toString().padStart(2, "0");
	});
	return time_str;
}

//判断数据类型
export function typeOf(obj) {
	const toString = Object.prototype.toString.call(obj);
	return toString.slice(8, -1);
}

// 获取路由传参
export function getParams() {
	const searchParams = new URLSearchParams(window.location.search);
	const params = Object.fromEntries(searchParams.entries());
	return params;
}

//颜色数组
export function getColorArr() {
	return ["#f50", "#2db7f5", "#87d068", "#108ee9"];
}

/**
 * @description:
 * @param {*} duration 时间
 * @param {*} from 来自
 * @param {*} to 去到
 * @param {*} callback 回调
 * @param {*} animation 动画
 * @return {*}
 */

function move(options, callback) {
	let { duration = 1000, from = 0, to = 10, animation = "easeInOut" } = options;
	function warp(resolve, reject) {
		let obj_animation = {
			//线性
			linear(t) {
				return t;
			},
			//缓入
			easeIn(t) {
				return t * t;
			},
			//缓出
			easeOut(t) {
				return 1 - Math.pow(1 - t, 2);
			},
			//缓入缓出
			easeInOut(t) {
				return 0.5 - Math.cos(t * Math.PI) / 2;
			},
			//弹性
			elastic(t) {
				return (0.04 * t) / Math.sin(25 * t + 7.5);
			},
			//反弹
			bounce(t) {
				if (t < 1 / 2.75) {
					return 7.5625 * t * t;
				} else if (t < 2 / 2.75) {
					t -= 1.5 / 2.75;
					return 7.5625 * t * t + 0.75;
				} else if (t < 2.5 / 2.75) {
					t -= 2.25 / 2.75;
					return 7.5625 * t * t + 0.9375;
				} else {
					t -= 2.625 / 2.75;
					return 7.5625 * t * t + 0.984375;
				}
			},
		};

		let dis = to - from; //需要执行距离
		let speed = dis / duration; //速度
		let start_time = Date.now(); //开始时间
		let value = from; //当前值

		function _run() {
			let now = Date.now(); //开始时间
			let end_time = now - start_time; // 过去的时间差

			if (end_time > duration) {
				value = to;
				callback(value);
				resolve(value);
				return; //结束
			}
			let progress = end_time / duration; // 动画进度（从0到1）
			let eased_progress = obj_animation[animation](progress); // 使用缓动函数计算经过缓动后的进度
			let d = end_time * speed; //已经移动的距离
			value = from + d * eased_progress; //当前值
			callback(value);
			requestAnimationFrame(_run);
		}
		requestAnimationFrame(_run);
	}

	return new Promise(warp);
}

// 防抖
export const debounce = (fn, delay = 1000) => {
	let timer = null;
	return function (args) {
		if (timer) clearTimeout(timer);
		timer = setTimeout(() => {
			fn.apply(this, args);
		}, delay);
	};
};
// 节流
export const throttle = (fn, delay = 1000) => {
	let timer = null;
	let flag = true;
	return function (args) {
		if (!flag) return;
		flag = false;
		timer = setTimeout(() => {
			fn.apply(this, args);
			flag = true;
		}, delay);
	};
};

// 下载文件流
export const upload_blob = (blob_file, file_name) => {
	let blob = new Blob([blob_file], { type: "application/octet-stream" });
	let a = document.createElement("a");
	a.href = window.URL.createObjectURL(blob);
	a.download = file_name;
	a.click();
	window.URL.revokeObjectURL(a.href);
	a = null;
};

// oss封面
export const oss_cover = (h = 600) => {
	return `?x-oss-process=video/snapshot,t_3000,f_jpg,w_800,h_${h},m_fast `;
};

// 获取后缀
export const getSuffix = (str = "x.x") => {
	return str.split(".").at(-1);
};
// 千分位
export const thousands = num => {
	if (typeof num == "string") {
		num = Number(num);
	}
	if (typeof num != "number") {
		return console.error("千分位请传参number");
	}
	return num.toLocaleString();
};

//数字转万 只到万
export function myriad_str(num, unit = ["", "万", "亿", "万亿"], unit_num = 10000) {
	if (typeof num == "string" || typeof num == "bigint") {
		num = Number(num);
	}
	if (typeof num != "number") {
		return console.error("数字转万请传参number");
	}
	if (num === 0) return "0";
	let str = "";
	for (let i = unit.length - 1; i >= 0; i--) {
		const divisor = Math.pow(unit_num, i);
		if (num >= divisor) {
			str += Math.floor(num / divisor) + unit[i];
			num %= divisor;
		}
	}
	return str;
}

/**
 * @description: 随机数整数
 * @param min
 * @param max
 * @return number
 */
export let random = (min, max) => {
	return Math.floor(Math.random() * (max - min + 1)) + min;
};

// 复制
export let copy = (text, callback = () => {}) => {
	if (window == undefined) return console.error("请在浏览器环境下使用copy");
	if (window.navigator.clipboard) {
		copy = (text, callback = () => {}) => {
			window.navigator.clipboard.writeText(text).then(callback);
		};
	} else {
		copy = (text, callback = () => {}) => {
			const dom = document.createElement("input");
			dom.value = text;
			document.body.appendChild(dom);
			dom.select();
			document.execCommand("copy");
			document.body.removeChild(dom);
			callback();
		};
	}
	copy(text, callback);
};

/** 随机颜色
 * @return string
 */
export let randomColor = (num = 0xffffff) => {
	return (
		"#" +
		Math.floor(Math.random() * num)
			.toString(16)
			.padStart(6, "0")
	);
};

/** 版本对比
 * @param version 0.0.0
 * @param version 1.1.1
 * @return 0 相等 1大于 -1小于
 */
export let versionCompare = (str1, str2) => {
	let reg = /^v?~?\^?(>=?)?\d{1,3}\.\d{1,3}\.\d{1,3}$/;
	if (!reg.test(str1) || !reg.test(str2)) return console.error("版本号格式错误 0.0.0");
	const replaceReg = /^v|~|\^|>=?/g;
	str1 = str1.replace(replaceReg, "");
	str2 = str2.replace(replaceReg, "");
	let arr1 = str1.split(".");
	let arr2 = str2.split(".");
	for (let i = 0; i <= 2; i++) {
		let num1 = parseInt(arr1[i]);
		let num2 = parseInt(arr2[i]);
		if (num1 > num2) {
			return 1;
		} else if (num1 < num2) {
			return -1;
		}
	}
	return 0;
};

/** 随机字符串
 * @return string
 */
const randomStr=()=>{
	return Math.random().toString(36).substr(2);
}
